package com.budwk.app.sqfwV2.generator.centuryCity;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfwDoc.bo.ExcelCreateConfig;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.CommonParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.ExcelGenerateParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.ExcelRowDataParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.BaseExcelGenerator;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.ResultOfExcelDataInto;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.ResultOfExcelGenerator;
import com.budwk.app.sqfwV2.dto.centuryCity.CenturyCityOldCarePdfDTO;
import com.budwk.app.sqfwV2.dto.centuryCity.CenturyCityProblemParamDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.ProblemParamDTO;
import com.budwk.app.sqfwV2.dto.image.CenturyCityOldCareExcelImageConfigBO;
import com.budwk.app.sqfwV2.enums.HiddenDangerEnum;
import com.budwk.app.sqfwV2.enums.centuryCityOldCare.CenturyCityOldCareV2FileEnums;
import com.budwk.app.sqfwV2.service.centuryCity.CenturyCityOldCareExcelService;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * @author 东方祥云低代码1.1
 * @since 2024-06-06
 * <p>
 * 世纪城养老服务站巡查1.1 CenturyCityOldCare
 * 食品安全排查台账.xlsx
 */
public class FoodSafetyInsLedgerExcelGenerator extends BaseExcelGenerator {

    private final ThreadLocal<ExcelCreateConfig> excelGenerateThreadLocal = ThreadLocal.withInitial(() -> null);

    private final Map<String, HiddenDangerEnumBO> hiddenDangerEnumBOMap;

    public FoodSafetyInsLedgerExcelGenerator() {
        Map<String, HiddenDangerEnumBO> hiddenDangerEnumTempMap = Maps.newHashMap();
        for (HiddenDangerEnum value : HiddenDangerEnum.values()) {
            HiddenDangerEnumBO hiddenDangerEnumBO = new HiddenDangerEnumBO();
            BeanUtil.copyProperties(value, hiddenDangerEnumBO);
            hiddenDangerEnumBO.setKey(value.getFlag());
            hiddenDangerEnumTempMap.put(value.getCode(), hiddenDangerEnumBO);
        }
        this.hiddenDangerEnumBOMap = hiddenDangerEnumTempMap;
    }

    @Override
    protected void createExcelStart(ExcelGenerateParam excelGenerateParam) {
        ExcelCreateConfig excelConfig = excelGenerateParam.getExcelConfig();
        excelGenerateThreadLocal.set(excelConfig);
    }

    @Override
    protected void createExcelEnd(ExcelGenerateParam excelGenerateParam, ExcelFileCreateParamBO excelFileCreateParam, ResultOfExcelGenerator result) {
        excelGenerateThreadLocal.remove();
    }

    /**
     * 自定义excel的表头数据
     *
     * @param excelParam         excel参数整体参数map
     * @param excelGenerateParam 创建excel所提供的参数
     */
    @Override
    protected void customerPopularHeaderData(Map<String, Object> excelParam, ExcelGenerateParam excelGenerateParam) {

    }

    /**
     * 后端自定义维护表头数据
     *
     * @param excelParam         excel整体参数
     * @param excelGenerateParam 创建excel所提供的参数
     */
    @Override
    protected void customerPopularHeaderDataForAdmin(Map<String, Object> excelParam, ExcelGenerateParam excelGenerateParam) {

    }

    /**
     * @param excelParam         excel整体参数
     * @param excelGenerateParam 创建excel所提供的参数
     * @return 判断excel是否含有数据
     */
    @Override
    protected ResultOfExcelDataInto judgeExcelHaveDataBeforeErgodic(Map<String, Object> excelParam, ExcelGenerateParam excelGenerateParam) {
        return null;
    }

    /**
     * 根据行数据判断是否该条数据进入excel中
     *
     * @param rowDataParam       行数据
     * @param excelGenerateParam excel生成所提供的参数
     * @return 是/否
     */
    @Override
    protected boolean addRowDataCondition(ExcelRowDataParam rowDataParam, ExcelGenerateParam excelGenerateParam) {
        CenturyCityOldCarePdfDTO fieldDTO = (CenturyCityOldCarePdfDTO) rowDataParam.getAbstractCustomerPdfCreateField();
        String fileOutputType = fieldDTO.getFileOutputType();
        return !fileOutputType.equals("无");
    }

    @Override
    protected void customerPopularSheetData(List<Map<String, Object>> listMap, ExcelGenerateParam excelGenerateParam) {

    }

    /**
     * 用户自定义填充excel实体数据
     *
     * @param listMap            数据数据
     * @param excelGenerateParam 创建excel所需的参数
     */
    @Override
    protected void popularSheetDataList(List<Map<String, Object>> listMap, ExcelGenerateParam excelGenerateParam) {
        List<ExcelRowDataParam> dataList = excelGenerateParam.getDataList();

        int rowDataIndex = 0;
        for (ExcelRowDataParam excelRowDataParam : dataList) {

            Sqfw_formSummary_new nextCheckFormSummary = (Sqfw_formSummary_new) excelRowDataParam.getCustomerParamMap()
                    .get(CenturyCityOldCareExcelService.nextFormSummaryName);

            Sqfw_formSummary_new lastCheckFormSummary = (Sqfw_formSummary_new) excelRowDataParam.getCustomerParamMap()
                    .get(CenturyCityOldCareExcelService.lastFormSummaryName);

            Set<String> nextCheckProblemSet = Sets.newHashSet();
            Map<String, ProblemParamDTO> nextCheckHiddenDangerMap = Maps.newHashMap();
            if (nextCheckFormSummary != null) {
                CenturyCityOldCarePdfDTO paramData = JSONObject.parseObject(nextCheckFormSummary.getParamData(), CenturyCityOldCarePdfDTO.class);
                List<ProblemParamDTO> allFoodCheckList = Lists.newArrayList();
                allFoodCheckList.addAll(Optional.ofNullable(paramData.getFoodServiceForm()).orElse(Lists.newArrayList()));
                allFoodCheckList.addAll(Optional.ofNullable(paramData.getFoodSaleForm()).orElse(Lists.newArrayList()));

                for (ProblemParamDTO foodCheckProblem : allFoodCheckList) {
                    String riskCode = foodCheckProblem.getRiskCode();
                    String key = foodCheckProblem.getKey();

                    HiddenDangerEnumBO hiddenDangerPro = hiddenDangerEnumBOMap.get(riskCode);
                    if (hiddenDangerPro.getFlag().equals(key)) {
                        nextCheckProblemSet.add(riskCode);
                    }

                    nextCheckHiddenDangerMap.put(riskCode, foodCheckProblem);
                }
            }

            CommonParam createUserCommonParam = excelRowDataParam.getCreateUserCommonParam();
            CenturyCityOldCareV2BusinessParam businessParam = (CenturyCityOldCareV2BusinessParam) excelRowDataParam.getBusinessParam();

            Sqfw_formSummary_new formSummaryNew = businessParam.getFormSummaryNew();
            Date fillDate = formSummaryNew.getFillDate();

            CenturyCityOldCarePdfDTO paramData = (CenturyCityOldCarePdfDTO) excelRowDataParam.getAbstractCustomerPdfCreateField();
            List<CenturyCityProblemParamDTO> foodServiceList = Optional.ofNullable(paramData.getFoodServiceForm()).orElse(Lists.newArrayList());
            List<CenturyCityProblemParamDTO> foodSaleList = Optional.ofNullable(paramData.getFoodSaleForm()).orElse(Lists.newArrayList());

            List<ProblemParamDTO> allFoodCheckList = Lists.newArrayList();
            allFoodCheckList.addAll(foodServiceList);
            allFoodCheckList.addAll(foodSaleList);

            boolean currentCheckNoProblemFlag = true;

            // 在这里添加一些方法来填充相应的数据
            for (ProblemParamDTO foodServiceItem : allFoodCheckList) {
                String riskCode = foodServiceItem.getRiskCode();
                String key = foodServiceItem.getKey();

                HiddenDangerEnumBO hiddenDanger = hiddenDangerEnumBOMap.get(riskCode);
                String hiddenDangerDefault = hiddenDanger.getFlag();
                if (!hiddenDangerDefault.equals(key)) continue;

                currentCheckNoProblemFlag = false;

                String riskDesc = foodServiceItem.getRiskDesc();    // 问题描述
                String riskImages = foodServiceItem.getRiskImages();    // 整改前照片
                String rectificationAfterPhoto = foodServiceItem.getRectificationAfterPhoto();  // 整改后照片
                String rectificationMeasure = foodServiceItem.getRectificationMeasure();    // 整改措施
                String remark = foodServiceItem.getRemark();
                String rectificateTypeCode = foodServiceItem.getRectificationTypeCode();  // 整改类别
                String rectificateTypeStr = rectificateTypeCode.equals("1") ? "已整改" : "整改中";

                // 如果下一次检查的问题中没有这个问题了，那么认为这个问题已经解决了,把下一次检查的整改后照片赋值到这里
                if (!nextCheckProblemSet.contains(riskCode)) {
                    ProblemParamDTO problemParamDTO = nextCheckHiddenDangerMap.get(riskCode);
                    if (problemParamDTO != null) {
                        rectificationAfterPhoto = problemParamDTO.getRectificationAfterPhoto();
                        rectificateTypeStr = "已整改";
                    }
                }

                // 这里需要判断什么样的问题才会进入表里面
                Map<String, Object> rowDataMap = Maps.newHashMap();
                rowDataMap.put("num", ++rowDataIndex);
                rowDataMap.put("community", formSummaryNew.getCommunity());
                rowDataMap.put("placeName", paramData.getPlaceName());
                rowDataMap.put("address", paramData.getAddress());
                rowDataMap.put("operatOraganHead", paramData.getOperatOraganHead());
                rowDataMap.put("operatOraganPhone", paramData.getOperatOraganPhone());
                rowDataMap.put("riskDesc", riskDesc);

                rowDataMap.put("handingOpinions", rectificateTypeStr);
                rowDataMap.put("rectificationMeasure", rectificationMeasure);

                Boolean createExcelFileFlag = excelGenerateThreadLocal.get().getCreateExcelFileFlag();
                if (createExcelFileFlag) {
                    rowDataMap.put("riskImages", CommonFormOfficeUtils.addPictureToByteList(riskImages, 2));
                    rowDataMap.put("rectificationAfterPhoto", CommonFormOfficeUtils.addPictureToByteList(rectificationAfterPhoto, 2));
                }

                String createUserSigUrl = createUserCommonParam.getCreateUserSigUrl();
                if (StringUtils.isNotBlank(createUserSigUrl)) {

                    if (createExcelFileFlag) {
                        rowDataMap.put("userSig", CommonFormOfficeUtils.addPictureToByteList(createUserSigUrl, 1));
                    }

                    rowDataMap.put("createUsername", "");
                } else {
                    rowDataMap.put("userSig", null);
                    rowDataMap.put("createUsername", createUserCommonParam.getCreateUserName());
                }
                rowDataMap.put("fillDateStr", DateUtil.format(fillDate, "yyyy-MM-dd"));
                rowDataMap.put("remark", remark);
                listMap.add(rowDataMap);
            }

            // 如果这一次检查一个问题都没有，还需要看上一条数据是否是有限期整改的情况,那么需要插入一条无的数据
            if (currentCheckNoProblemFlag && judgeLastCheckNotHaveDeadLineCheck(lastCheckFormSummary)) {
                rowDataIndex++;
                Map<String, Object> noProblemRowDataMap = createNoProblemRowDataMap(rowDataIndex, formSummaryNew, paramData, createUserCommonParam);
                listMap.add(noProblemRowDataMap);
            }
        }
    }

    /**
     * 自定义填充excel中每一行的数据
     *
     * @param rowDataMap   当前行的数据Map
     * @param rowDataParam 所提供的当前行的数据
     */
    @Override
    protected void customerPopularRowDataMap(Map<String, Object> rowDataMap, ExcelRowDataParam rowDataParam) {
        CenturyCityOldCarePdfDTO fieldDTO = (CenturyCityOldCarePdfDTO) rowDataParam.getAbstractCustomerPdfCreateField();
    }

    /**
     * 后端生成excel时候自定义填充excel中每一行的数据
     *
     * @param rowDataMap   当前行的数据Map
     * @param rowDataParam 所提供的当前行的数据
     */
    @Override
    protected void customerPopularRowDataMapForAdmin(Map<String, Object> rowDataMap, ExcelRowDataParam rowDataParam) {
        CenturyCityOldCarePdfDTO fieldDTO = (CenturyCityOldCarePdfDTO) rowDataParam.getAbstractCustomerPdfCreateField();
    }

    /**
     * 在创建之前判断excel中是否含有数据
     *
     * @param excelParam         创建之前excel中已经填充的数据
     * @param excelGenerateParam 所提供的excel创建的所需要的数据
     * @return 结果
     */
    @Override
    protected ResultOfExcelDataInto judgeExcelHaveDataBeforeCreate(Map<String, Object> excelParam, ExcelGenerateParam excelGenerateParam) {
        List list = (List) excelParam.get("list");
        if (CollectionUtil.isEmpty(list)) {
            ResultOfExcelDataInto resultOfExcelDataInto = new ResultOfExcelDataInto();
            resultOfExcelDataInto.setExcelHaveDataFlag(false);
            return resultOfExcelDataInto;
        }

        return null;
    }

    @Override
    protected String getTemplatePath(ExcelGenerateParam excelGenerateParam) {
        return CenturyCityOldCareV2FileEnums.foodSafetyInsLedgerExcel.getPath();
    }

    /**
     * 可以参照 {@link com.budwk.app.sqfw.enums.DownLoadFileNameEnum}
     *
     * @return 文件名名称
     */
    @Override
    public String getDownloadFileName(ExcelGenerateParam excelGenerateParam) {
        // 注意注意注意不用带上后缀
        return CenturyCityOldCareV2FileEnums.foodSafetyInsLedgerExcel.getDownloadFileName();
    }


    @Override
    protected Class<?> getImageConfigBO() {
        return CenturyCityOldCareExcelImageConfigBO.class;
    }

    /**
     * 允许用户在创建excel文件之前对配置进行修改
     *
     * @param excelFileCreateParamBO 创建excel的配置参数
     */
    @Override
    protected void completeExcelFileCreateParam(ExcelFileCreateParamBO excelFileCreateParamBO) {

    }

    // --------------------------------------------------------------------
    // 下面是一些私有的方法
    // --------------------------------------------------------------------
    private Map<String, Object> createNoProblemRowDataMap(Integer rowDataIndex, Sqfw_formSummary_new formSummaryNew, CenturyCityOldCarePdfDTO paramData, CommonParam createUserCommonParam) {
        Map<String, Object> rowDataMap = Maps.newHashMap();
        rowDataMap.put("num", rowDataIndex);
        rowDataMap.put("community", formSummaryNew.getCommunity());
        rowDataMap.put("placeName", paramData.getPlaceName());
        rowDataMap.put("address", paramData.getAddress());
        rowDataMap.put("operatOraganHead", paramData.getOperatOraganHead());
        rowDataMap.put("operatOraganPhone", paramData.getOperatOraganPhone());
        rowDataMap.put("riskDesc", "无");
        rowDataMap.put("riskImages", null);
        rowDataMap.put("handingOpinions", "无");
        rowDataMap.put("rectificationMeasure", "无");
        rowDataMap.put("rectificationAfterPhoto", null);
        String createUserSigUrl = createUserCommonParam.getCreateUserSigUrl();
        if (StringUtils.isNotBlank(createUserSigUrl)) {
            rowDataMap.put("userSig", CommonFormOfficeUtils.addPictureToByteList(createUserSigUrl, 1));
            rowDataMap.put("createUsername", "");
        } else {
            rowDataMap.put("userSig", null);
            rowDataMap.put("createUsername", createUserCommonParam.getCreateUserName());
        }
        rowDataMap.put("fillDateStr", DateUtil.format(paramData.getInspectionDate(), "yyyy-MM-dd"));
        rowDataMap.put("remark", "");
        return rowDataMap;
    }

    private Boolean judgeLastCheckNotHaveDeadLineCheck(Sqfw_formSummary_new lastCheckFormSummary) {

        boolean lastCheckNotHaveDeadLineCheckFlag = true;

        if (lastCheckFormSummary != null) {
            String lastCheckParamDataStr = lastCheckFormSummary.getParamData();
            if (StringUtils.isNotBlank(lastCheckParamDataStr)) {
                CenturyCityOldCarePdfDTO lastCheckParamData = JSONObject.parseObject(lastCheckParamDataStr, CenturyCityOldCarePdfDTO.class);
                List<CenturyCityProblemParamDTO> foodSaleForm = Optional.ofNullable(lastCheckParamData.getFoodSaleForm()).orElse(Lists.newArrayList());
                List<CenturyCityProblemParamDTO> foodServiceForm = Optional.ofNullable(lastCheckParamData.getFoodServiceForm()).orElse(Lists.newArrayList());

                List<ProblemParamDTO> allList = Lists.newArrayList();
                allList.addAll(foodSaleForm);
                allList.addAll(foodServiceForm);

                for (ProblemParamDTO problemParamDTO : allList) {
                    String rectificationTypeCode = problemParamDTO.getRectificationTypeCode();
                    if (StringUtils.isNotBlank(rectificationTypeCode)) {
                        if (rectificationTypeCode.equals("5")) {
                            lastCheckNotHaveDeadLineCheckFlag = false;
                            break;
                        }
                    }
                }
            }
        }

        return lastCheckNotHaveDeadLineCheckFlag;
    }
}
